import sys
import time, tkMessageBox
import Controller

try:
        import pygtk
        pygtk.require("2.0")
except:
        pass
try:
        import gtk
        import gtk.glade
except:
        sys.exit(1)

########################################################################
class JanelaPrincipal:
        
        def __init__(self):         
                # Cria uma nova janela (window)
                self.janela = gtk.Window(gtk.WINDOW_TOPLEVEL)
                self.janela.set_position(gtk.WIN_POS_CENTER)
                self.janela.set_title('Scanner 1Clic2Learn' )
                self.janela.set_size_request(1050, 700)
                self.janela.set_resizable(False)
                self.janela.set_icon_name('1Clic2Learn')
                self.janela.set_icon_from_file('./1Clic2Learn-3-Icon.ico')
                
                # Adicionando os wigets a janela "
                self.fixed = gtk.Fixed()
                self.janela.add(self.fixed)
                self.fixed.put(gtk.Label('URL da Aplicacao: '), 50, 30)
                self.txtURL = gtk.Entry()
                self.txtURL.set_size_request(650, 30)
                self.fixed.put(self.txtURL, 200, 30)
                self.btExplorar = gtk.Button('Explorar' )
                self.btExplorar.set_size_request(100, 30)
                self.btExplorar.connect("clicked", self.IniciarExploracao)
                self.fixed.put(self.btExplorar, 900, 30)
                self.fixed.put(gtk.Label('Vulnerabilidades: ' ), 50, 90)
                
                #criando combo box
                self.ListVuln = gtk.ListStore(int,str)
                self.ListVuln.append([1, "SQL Injection"])
                self.ListVuln.append([2,"Cross-Site Scripiting"])

                self.ComboVul = gtk.combo_box_new_with_model_and_entry (self.ListVuln)
                self.ComboVul.set_entry_text_column(1)
                self.ComboVul.connect("changed", self.on_name_combo_changed)
                self.ComboVul.set_size_request(300,30)
                self.ComboVul.set_active(0)
                self.fixed.put(self.ComboVul, 200, 90)
                
                #check box para criterio de parada
                self.checkParada = gtk.CheckButton('Parar ao encontrar a primeira falha')
                self.checkParada.set_size_request(300, 30)
                self.checkParada.set_active(1)
                self.fixed.put(self.checkParada, 600, 90)                
##############################RESULTADO###########################################################
                # Criando a janela para receber o resultado dos ataques.
                self.scrollwinResult = gtk.ScrolledWindow()
                self.scrollwinResult.set_size_request(535,500)
                self.scrollwinResult.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
                self.listResult = gtk.ListStore(str, str, str, str, str, 'gboolean')
                # Criando Treeview com uma lista
                self.treeview = gtk.TreeView(self.listResult)
                self.scrollwinResult.add(self.treeview)
                self.fixed.put(self.scrollwinResult,50,150)
                 
                # Criando cabecalho das colunas
                self.tvcolumn = gtk.TreeViewColumn('Situacao')
                self.tvcolumn.set_alignment(xalign=0.5)
                self.tvcolumn1 = gtk.TreeViewColumn('Criticidade')
                self.tvcolumn1.set_alignment(xalign=0.5)
                self.tvcolumn2 = gtk.TreeViewColumn('URL')
                self.tvcolumn2.set_alignment(xalign=0.5)
                self.tvcolumn3 = gtk.TreeViewColumn('Componente Testado')  
                self.tvcolumn3.set_alignment(xalign=0.5)
                
                # aadiciona colunas na treeview/tabela
                self.treeview.append_column(self.tvcolumn)
                self.treeview.append_column(self.tvcolumn1)
                self.treeview.append_column(self.tvcolumn2)
                self.treeview.append_column(self.tvcolumn3)
                
                # criando as cedulas        
                self.cellFalha = gtk.CellRendererText()
                self.cellCrit = gtk.CellRendererText()
                self.cellCrit.set_alignment(xalign=0.5, yalign=0.5)
                self.cellComp = gtk.CellRendererText()
                self.cellTest = gtk.CellRendererText()
                # set cor de fundo
                self.cellFalha.set_property("foreground", "red")
                
                # adicionando cedulas nas colunas 
                self.tvcolumn.pack_start(self.cellFalha, True)
                self.tvcolumn1.pack_start(self.cellCrit, True)
                self.tvcolumn2.pack_start(self.cellComp, True)
                self.tvcolumn3.pack_start(self.cellTest, True)                
                self.tvcolumn.set_attributes(self.cellFalha, text=0)
                self.tvcolumn1.set_attributes(self.cellCrit, text=1)
                self.tvcolumn2.set_attributes(self.cellComp, text=2)
                self.tvcolumn3.set_attributes(self.cellTest, text=3)
                
                # setando opcao para pesquisa
                self.treeview.set_search_column(0)     
                # Permitindo Ordenacao nas colunas
                self.tvcolumn.set_sort_column_id(0)
                self.tvcolumn1.set_sort_column_id(0)
                self.tvcolumn2.set_sort_column_id(0)
                self.tvcolumn3.set_sort_column_id(0)
                self.LabelInfo = gtk.Label()
                self.LabelInforServer = gtk.Label()
                self.LabelResultado = gtk.Label()
                self.LabelMitigacao = gtk.Label()
                self.LabelInforServer.set_markup("<b>Informacoes do Servidor:</b>")
                self.fixed.put(self.LabelInforServer, 600, 130)                
                self.LabelResultado.set_markup("<b>Resultados:</b>")
                self.fixed.put(self.LabelResultado, 50, 130)
                self.LabelMitigacao.set_markup("<b>Mitigacao:</b>")
                self.fixed.put(self.LabelMitigacao, 600, 360)  
                
                #CRIANDO CAMPO DE INFORMACOES DO SERVIDOR
                self.scrollwinServer = gtk.ScrolledWindow()
                self.scrollwinServer.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)                
                self.InfoServer = gtk.TextBuffer()
                self.TextViewServer = gtk.TextView(self.InfoServer)
                self.TextViewServer.set_editable(False)
                self.TextViewServer.set_cursor_visible(False)
                self.TextViewServer.set_wrap_mode(gtk.WRAP_WORD)
                self.TextViewServer.set_size_request(400,170)    
                self.scrollwinServer.add(self.TextViewServer)
                self.fixed.put(self.scrollwinServer, 600, 150)
                
                #CRIANDO CAMPO DE INFORMACOES DE MITIGACAO
                self.scrollwinMit = gtk.ScrolledWindow()
                self.scrollwinMit.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
                self.TextBufferMitigacao = gtk.TextBuffer()
                self.TextViewMit = gtk.TextView(self.TextBufferMitigacao)
                self.TextViewMit.set_editable(False)
                self.TextViewMit.set_cursor_visible(False)
                self.TextViewMit.set_wrap_mode(gtk.WRAP_WORD)
                self.TextViewMit.set_size_request(400,270)
                self.scrollwinMit.add(self.TextViewMit)
                self.fixed.put(self.scrollwinMit,600,380)
                
                #conectando a janela aos destrutores para finalizar o programa
                self.janela.connect('delete_event', self.delete_event)
                self.janela.connect('destroy', self.destroy)
                self.janela.show_all()        
        
        def ShowError(self, title, mensagem):
                dialog = gtk.MessageDialog(parent=self.janela,flags=gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
                type=gtk.MESSAGE_INFO, buttons=gtk.BUTTONS_OK,
                message_format=mensagem)
                dialog.set_title(title)
                dialog.set_position(gtk.WIN_POS_CENTER_ALWAYS)
                # Exibe a caixa
                dialog.run()
                dialog.destroy()                
        
        def IniciarExploracao(self, widget, data=None):
       
                Inicial= time.time()
                print "Start : %s" %Inicial
                #LIMPANDO AS VARIAVEIS DA JANELA
                                
                self.TextBufferMitigacao.set_text("")
                self.listResult.clear()                
                #self.progressbar.destroy()                            
                self.InfoServer.set_text("")
                self.selc = self.on_name_combo_changed(self.ComboVul)
                
                #VERIFICANDO SE EXISTE URL
                if self.txtURL.get_text() == "":
                # EXIBINDO UMA POPUP DE ALERTA
                        self.ShowError('ALERTA', 'ATENCAO: Favor preencher o campo URL da Aplicacao!')
                #VERIFICANDO SE FOI SELECIONADA ALGUMA OPCAO
                elif (self.selc > 2) or (self.selc == 999):
                        self.InfoServer.set_text("")
                        self.listResult.clear()
                else:                     
                        # Utilizando a classe CONTROLLER
                        self.control = Controller.Controller(self.txtURL.get_text())
                        self.control.select_Plugin(self.selc,self.checkParada.state) #envia o plugin e o criterio de parada(1 - para no primeiro)
                        self.teste_url = []
                        self.teste_url = self.control.check_URL()
                        
                        if len(self.teste_url) == 2:  # se a lista tiver 2 colunas entao ocorreu um erro
                                self.ShowError(str(self.teste_url[0]), str(self.teste_url[1]))
                        else:        
                                #INSERIR AS INFORMACOES DO SERVIDOR
                                self.a = []
                                self.a.append(self.control.get_Server_Info())
                                self.b = str()
                                for n in self.a:
                                        self.b = (str(n))
                                self.InfoServer.set_text(self.b)
                               
                                # ADICIONA O RESULTADO DO ATAQUE NA LISTA
                                self.resultado = []
                                self.resultado = self.control.send_Exploiter()
                                try:
                                        if len(self.resultado[0]) == 2 and self.resultado[0] == None:
                                                self.ShowError(str(self.resultado[0]), str(self.resultado[1]))
                                except:
                                        pass                                
                                else:
                                        for res in self.resultado:
                                                self.listResult.append(res)
                               
                                #AQUI deve passar a lista da Controller
                                self.treeview.set_model(self.listResult)
                                TempoFinal = round (time.time() - Inicial, 2)
                                
                                print TempoFinal
                                self.ShowError("SUCESSO!", "Exploração realizado com sucesso! \nTempo de Execução: " + str(TempoFinal) + ' segundos')
                                                
                        #Exibindo o texto de mitigacao quando selecionar o resultado!
                        self.selecao = self.treeview.get_selection()
                        self.selecao.connect('changed', self.on_select_change)
                        self.janela.show_all()

        # Retornando False (falso) nesta funcao o GTK ira emitir o sinal de "destroy". Se voce retornar True
        # (verdadeiro),significa que voce nao quer que a janela seja fechada
        def delete_event(self, widget, event, data=None):
                print "Programa encerrado!"
                return False
        
        #FUNCAO CRIADA PARA VERIFICAR O ITEM SELECIONADO NA TREEVIEW SELECIONADA
        def on_select_change(self, widget):

                m, itr = widget.get_selected()
                if itr:
                        #Exibe o item da posicao 4 - mitigacao se for vulnerável
                        if m[itr][5]:
                                self.TextBufferMitigacao.set_text(m[itr][4])
                                self.scrollwinMit.show_all()
                        else:
                                self.TextBufferMitigacao.set_text("")
                                self.scrollwinMit.show_all()                        
                        
        def on_name_combo_changed(self, combo):
                tree_iter = combo.get_active_iter()
                model = combo.get_model()
                
                if tree_iter == None:
                        self.ShowError('ATENCAO','Nenhuma vulnerabilidade foi selecionada!')
                        return 999
                else:
                        row_id, name = model[tree_iter]
                        return row_id

        # Outro retorno
        def destroy(self, widget, data=None):
                gtk.main_quit()
           

        def main(self):
                gtk.main()

# Se o programa rodar diretamente ou for passado como um argumento para o interpretador de python
# ele criara a JanelaPrincipal e o mostrara.
if __name__ == "__main__":
        Janela = JanelaPrincipal()
        Janela.main()